package com.maxbill.utils;

import java.io.InputStream;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.io.IOUtils;

public class HdfsUtils {

	private final static String userPath = "/user/hadoop/";
	private final static String hdfsPath = "hdfs://192.168.1.10:9000";

	/**
	 * @功能 获取HDFS配置信息
	 * @作者 zuoshuai(MaxBill)
	 */
	private static Configuration getHdfsConfig() {
		Configuration config = new Configuration();
		return config;
	}

	/**
	 * @功能 获取FS对象
	 * @作者 zuoshuai(MaxBill)
	 */
	private static FileSystem getFileSystem() throws Exception {
		FileSystem hdfs = FileSystem.get(new URI(hdfsPath), getHdfsConfig(), "hadoop");
		return hdfs;
	}

	/**
	 * @功能 在HDFS创建文件夹
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void mkdir(String path) throws Exception {
		FileSystem fs = getFileSystem();
		Path srcPath = new Path(path);
		boolean isOk = fs.mkdirs(srcPath);
		if (isOk) {
			System.out.println("create dir success...");
		} else {
			System.out.println("create dir failure...");
		}
		fs.close();
	}

	/**
	 * @功能 在HDFS创建文件
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void createFile(String filePath, byte[] files) throws Exception {
		FileSystem fs = getFileSystem();
		// 目标路径
		Path path = new Path(filePath);
		// 打开一个输出流
		FSDataOutputStream outputStream = fs.create(path);
		outputStream.write(files);
		outputStream.close();
		fs.close();
	}

	/**
	 * @功能 读取HDFS文件内容
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void readFile(String filePath) throws Exception {
		FileSystem fs = getFileSystem();
		Path path = new Path(filePath);
		InputStream in = null;
		try {
			in = fs.open(path);
			// 复制到标准输出流
			IOUtils.copyBytes(in, System.out, 4096, false);
		} finally {
			IOUtils.closeStream(in);
		}
	}

	/**
	 * @功能 读取HDFS目录详细信息
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void pathInfo(String filePath) throws Exception {
		FileSystem fs = getFileSystem();
		FileStatus[] listStatus = fs.listStatus(new Path(filePath));
		for (FileStatus fileStatus : listStatus) {
			System.out.println(fileStatus.getPath() + ">>>>>" + fileStatus.toString());
		}
	}

	/**
	 * @功能 读取HDFS文件列表
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void listFile(String filePath) throws Exception {
		FileSystem fs = getFileSystem();
		// 递归找到所有的文件
		RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path(filePath), true);
		while (listFiles.hasNext()) {
			LocatedFileStatus next = listFiles.next();
			String name = next.getPath().getName();
			Path path = next.getPath();
			System.out.println(name + "---" + path.toString());
		}
	}

	/**
	 * @功能 文件重命名
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void renameFile(String oldName, String newName) throws Exception {
		FileSystem fs = getFileSystem();
		Path oldPath = new Path(oldName);
		Path newPath = new Path(newName);
		boolean isOk = fs.rename(oldPath, newPath);
		if (isOk) {
			System.out.println("rename success...");
		} else {
			System.out.println("rename failure...");
		}
		fs.close();
	}

	/**
	 * @功能 删除文件
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void deleteFile(String filePath) throws Exception {
		FileSystem fs = getFileSystem();
		Path path = new Path(filePath);
		boolean isOk = fs.deleteOnExit(path);
		if (isOk) {
			System.out.println("delete success...");
		} else {
			System.out.println("delete failure...");
		}
		fs.close();
	}

	/**
	 * @功能 上传文件
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void uploadFile(String fileName, String uplaodPath) throws Exception {
		FileSystem fs = getFileSystem();
		// 上传路径
		Path clientPath = new Path(fileName);
		// 目标路径
		Path serverPath = new Path(uplaodPath);
		// 调用文件系统的文件复制方法,前面参数是指是否删除原文件，true为删除，默认为false
		fs.copyFromLocalFile(false, clientPath, serverPath);
		fs.close();
	}

	/**
	 * @功能 下载文件
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void downloadFile(String fileName, String downPath) throws Exception {
		FileSystem fs = getFileSystem();
		fs.copyToLocalFile(new Path(fileName), new Path(downPath));
		fs.close();
	}

	/**
	 * @功能 判断文件是否存在
	 * @作者 zuoshuai(MaxBill)
	 */
	public boolean existFile(String FileName) throws Exception {
		FileSystem hdfs = getFileSystem();
		Path path = new Path(FileName);
		boolean isExists = hdfs.exists(path);
		return isExists;
	}

	/**
	 * @功能 主类测试
	 * @作者 zuoshuai(MaxBill)
	 */
	public static void main(String args[]) throws Exception {
		// 测试创建目录
		// mkdir("demo");
		// 测试创建文件
		// byte[] files = "hello world".getBytes();
		// createFile(userPath + "demo/maxbill.txt", files);
		// 测试读取文件
		// readFile(userPath + "demo/maxbill.txt");
		// 读取目录信息
		// pathInfo(userPath);
		// 读取目录文件
		// listFile(userPath);
		// 测试重命名
		// renameFile(userPath + "demo/maxbill.txt", userPath + "demo/shuai.txt");
		// 测试删除文件
		// deleteFile(userPath + "demo/shuai.txt");
		// 测试上传文件
		// uploadFile("D:\\hello.txt", userPath + "demo/");
		// 测试下载文件
		downloadFile(userPath + "demo/hello.txt", "D:\\");
	}

}
